package com.spring.pay.cmb.service.impl;

import java.math.BigDecimal;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alipay.api.AlipayApiException;
import com.spring.common.redis.JedisManager;
import com.spring.pay.alipay.service.impl.AlipayServiceImpl;
import com.spring.pay.cmb.config.CmbConfig;
import com.spring.pay.cmb.service.ICmbpayService;
import com.spring.pay.cmb.util.CmbHttpClient;
import com.spring.pay.cmb.util.OsNameUtil;
import com.spring.pay.cmb.util.SubStringUtil;
import com.spring.pay.weixin.util.XMLUtil;
import com.spring.trade.po.TradeOrderInfo;
import com.spring.trade.service.ITradeOrderInfoService;
import com.spring.util.DateUtils;
import com.spring.util.IdentityHelper;
import com.spring.util.TradeOrderInfoStatus;
import com.spring.util.constant.Constant;

import cmb.netpayment.Security;

/** 
* @author  作者 E-mail: liuyang
* @date 创建时间：2016年10月25日 上午9:56:44 
* @version 2.0 
* @parameter  
* @since  
* @return  
*/
@Service
public class ICmbpayServiceImpl implements ICmbpayService {

	private Logger LOGGER = Logger.getLogger(AlipayServiceImpl.class);
	@Autowired
	private ITradeOrderInfoService tradeOrderInfoServiceImpl;


/*	@Autowired
	private IDocDoctorInfoService doctorInfoService;
	
	@Autowired
	private ITradeServiceInfoService tradeServiceInfoService;
	@Autowired
	private IPatientCustomerService patientCustomerService;
	@Autowired
	private IPatientBuyCallService patientBuyCallService;
	*/
	

	
	@Override
	public String receiveNotify(String queryStr,Map<String, String[]> requestMap) {
		try {
				
		/*	LOGGER.error("public.key 的路径是："+ICmbpayServiceImpl.class.getClassLoader().getResource(CmbConfig.PUBLIC_KEY).toString().substring(5));
			LOGGER.error("public.key 的路径是："+ICmbpayServiceImpl.class.getClassLoader().getResource(CmbConfig.PUBLIC_KEY).toString().substring(6));*/
			//去掉路径前的 file:/ (win系统不要/,去掉6位,linux要/,只去掉5位,用getSub方法判断系统)
			String urlStr = ICmbpayServiceImpl.class.getClassLoader().getResource(CmbConfig.PUBLIC_KEY).toString().substring(OsNameUtil.getOsNameValue());
			LOGGER.error("public.key 的路径是："+urlStr);
	        Security security = new Security(urlStr);
	        
	        boolean baMessage = security.checkInfoFromBank(queryStr.getBytes());
			
			if (!baMessage) {
				LOGGER.info("一网通回调签名校验失败！");
				return "faild";
			}

			LOGGER.info("一网通回调签名校验成功！");
			//orderNo=HXQ1477364989320OQKQ
			String MerchantPara  = 	requestMap.get("MerchantPara")[0];
			//得到订单号
			String orderNo = MerchantPara.split("=")[1];
			
			// 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
			TradeOrderInfo info = tradeOrderInfoServiceImpl.selectByorderNo(orderNo); // out_trade_no
			if(!StringUtils.isEmpty(info.getPayOrderNo())){
				LOGGER.info("回调方法已经执行！");
				return "";
			}
			
			//如果一网通返回的折扣金额不为空
			if(requestMap.get("DiscountFlag")!=null){
				String discountFlag=requestMap.get("DiscountFlag")[0];
				if(discountFlag.equals("Y")){
					String discountAmt=requestMap.get("DiscountAmt")[0];
					info.setDiscountAmount(new BigDecimal(discountAmt));
				}
			}
			
					
			// 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）
			//银行通知商户的支付结果消息；信息的前38个字符格式为：4位分行号＋6位商户号＋8位银行接受交易的日期＋20位银行流水号 	可以利用交易日期＋银行流水号＋定单号对该定单进行结帐处理 
			String msg = requestMap.get("Msg")[0];
			//截取后20位，银行流水号
			String payOrderNo = SubStringUtil.subString(msg, 20);

			info.setPayOrderNo(payOrderNo);
			info.setPayTime(DateUtils.getDate());
			info.setStatus(TradeOrderInfoStatus.ORDER_PAY.getValue()); // 1 已支付
			info.setPayType(Constant.cmbPay);
			tradeOrderInfoServiceImpl.updateByPrimaryKeySelective(info);
			JedisManager.setObject(info.getOrderNo(), 0, TradeOrderInfoStatus.ORDER_PAY.getValue());
			LOGGER.info("一网通回调处理成功！");
/*			DocDoctorInfo doctorInfo = doctorInfoService.selectDocDoctorInfoKey(info.getDoctorId());
			PatientCustomer patientCustomer = patientCustomerService.selectByPrimaryKey(info.getPatientId());
			Integer hourNum = BaseDataInitialize.getMsgCount(1, Constant.IMAGE_TEXT_RULE_HOUR_CODE);
			Integer msgNum = BaseDataInitialize.getMsgCount(1, Constant.IMAGE_TEXT_RULE_NUM_CODE);
			TradeServiceInfo serviceInfo2 = tradeServiceInfoService.selectByPrimaryKey(info.getServiceType());
			
			
			LinkedHashMap<String, String> jsonMap =null;
			if(info.getServiceType()==ServiceTypeConstants.TEXT.getValue()){
				jsonMap =new LinkedHashMap<>();
				jsonMap.put("patientName", StringUtils.isBlank(patientCustomer.getName())?"有患者":patientCustomer.getName());
				jsonMap.put("serviceName", serviceInfo2.getName());
				jsonMap.put("hour", hourNum+"");
				jsonMap.put("msgNum", msgNum+"");
				AliSmsService.sendSMS(doctorInfo.getMobile(),jsonMap,AliSmsService.CREATE_ORDER_TEMPID);
			}else if(info.getServiceType()==ServiceTypeConstants.TEL.getValue()){
				CallPatient callPatient =new CallPatient();
				callPatient.setOrderNo(info.getOrderNo());
				CallPatientDto patientDto = patientBuyCallService.getCallPatientInfo(callPatient);
				//患者购买医生电话服务短信--患者端
				jsonMap =new LinkedHashMap<>();
				jsonMap.put("docName", doctorInfo.getName());
				AliSmsService.sendSMS(patientCustomer.getMobile(),jsonMap,AliSmsService.CREATE_TEL_ORDER_PATIENT);
				//患者购买医生电话服务短信--医生端
				jsonMap =new LinkedHashMap<>();
				jsonMap.put("patientName",patientDto.getPatientName());
				jsonMap.put("callTalkTime", info.getCallDuration()+"");
				AliSmsService.sendSMS(doctorInfo.getMobile(),jsonMap,AliSmsService.CREATE_TEL_ORDER_DOCTOR);
				
			}
			doctorInfoService.updateActiveTime(info.getDoctorId());*/
			return "success";

		} catch (AlipayApiException e) {
			e.printStackTrace();
			LOGGER.error("一网通接口回调错误！");
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("一网通接口系统错误！");
		}
		return "faild";
	}
	
	
	@Override
	public String queryCmbOrder(String orderNo){
		
		CmbHttpClient httpClient = new CmbHttpClient();
		
		//根据订单号,截取最后10位，做为一网通的订单号
		String billNo = SubStringUtil.subString(orderNo, 10);
		
		TradeOrderInfo info = tradeOrderInfoServiceImpl.selectByorderNo(orderNo); // out_trade_no
		if (info == null) {
			LOGGER.error("订单号不存在");
			return "订单号不存在";
		}
		 
		String date = DateUtils.formatYyyymmddTime(info.getCreateTime());
		//单笔订单查询
		long timestamp1 = httpClient.getCurrentMs() - httpClient.dateToMs(CmbConfig.CMB_DEFAULT_DATE);
		StringBuffer head1 = new StringBuffer();
		head1.append("<BranchNo>").append(CmbConfig.BRANCH_ID).append("</BranchNo>");
		head1.append("<MerchantNo>").append(CmbConfig.CO_NO).append("</MerchantNo>");
		head1.append("<TimeStamp>" + timestamp1 + "</TimeStamp>");
		head1.append("<Command>QuerySingleOrder</Command>");

		StringBuffer body1 = new StringBuffer();
		body1.append("<Date>").append(date).append("</Date>");
		body1.append("<BillNo>").append(billNo).append("</BillNo>");

		StringBuffer sb1 = new StringBuffer();
		sb1.append("<Request><Head>");
		sb1.append(head1);
		sb1.append("</Head><Body>");
		sb1.append(body1);
		sb1.append("</Body><Hash>");
		sb1.append(httpClient.Encrypt(CmbConfig.SECRET_KEY + head1.toString() + body1.toString(), "SHA-1"));
		sb1.append("</Hash></Request>");
		
		String msg = httpClient.sendPost(CmbConfig.REFUND_URL + "?Request=" + sb1.toString(), "");
		
		return msg;
	}
	
	
	/**
	 * 一网通退款接口
	 * @param out_trade_no 平台订单号
	 * @return
	 */
	public String refundRequest(TradeOrderInfo tradeOrderInfoTemp){

		
		// 发送请求
		String strResponse = null;
		
		try {
			
			
			
			CmbHttpClient httpClient = new CmbHttpClient();
			
			String orderNo = tradeOrderInfoTemp.getOrderNo();
			
			TradeOrderInfo info = tradeOrderInfoServiceImpl.selectByorderNo(orderNo);
			
			if (info == null) {
				return "订单号不存在";
			}
			
			//根据订单号,截取最后10位，做为一网通的订单号
			String billNo = SubStringUtil.subString(orderNo, 10);
			
			//退款流水号
			String refundNo = IdentityHelper.randomString(15);
			
			//discountAmount
			//退款金额=(订单金额减优惠金额)
			String amount  = null;
			if(info.getDiscountAmount() != null && info.getDiscountAmount().compareTo(new BigDecimal(0)) != 0){
				amount = info.getOrderMoney().subtract(info.getDiscountAmount()).toString();
			}else{
				amount = info.getOrderMoney().toString();
			}
			
		
	
			 
			String date = DateUtils.formatYyyymmddTime(info.getCreateTime());
			//单笔订单查询
			long timestamp1 = httpClient.getCurrentMs() - httpClient.dateToMs(CmbConfig.CMB_DEFAULT_DATE);
			StringBuffer head1 = new StringBuffer();
			head1.append("<BranchNo>").append(CmbConfig.BRANCH_ID).append("</BranchNo>");
			head1.append("<MerchantNo>").append(CmbConfig.CO_NO).append("</MerchantNo>");
			head1.append("<Operator>").append(CmbConfig.OPERATOR).append("</Operator>");
			head1.append("<Password>").append(CmbConfig.PASSWORD).append("</Password>");
			head1.append("<TimeStamp>" + timestamp1 + "</TimeStamp>");
			head1.append("<Command>Refund_No_Dup</Command>");
			
			System.out.println("head1 is :" + head1.toString());

			StringBuffer body1 = new StringBuffer();
			body1.append("<Date>").append(date).append("</Date>");
			body1.append("<BillNo>").append(billNo).append("</BillNo>");
			body1.append("<RefundNo>").append(refundNo).append("</RefundNo>");
			body1.append("<Amount>").append(amount).append("</Amount>");
			body1.append("<Desc>").append(orderNo).append("</Desc>"); //一网通暂不支持中文
			
			
			StringBuffer sb1 = new StringBuffer();
			sb1.append("<Request><Head>");
			sb1.append(head1);
			sb1.append("</Head><Body>");
			sb1.append(body1);
			sb1.append("</Body><Hash>");
			
			StringBuffer strSrc = new StringBuffer();
			strSrc.append(CmbConfig.SECRET_KEY).append(head1.toString()).append(body1.toString());
			
			
			sb1.append(httpClient.Encrypt(strSrc.toString(), "SHA-1"));
		
			
			sb1.append("</Hash></Request>");
			
					
			
			String msg = httpClient.sendPost(CmbConfig.REFUND_URL + "?Request=" + sb1.toString(), "");
			Map map	 = XMLUtil.doXMLParse(msg);
			StringBuffer buff = new StringBuffer("<xml>");
			buff.append((String)map.get("Head"));
			buff.append("</xml>");
			map = XMLUtil.doXMLParse(buff.toString());
					
			String resCode = (String)map.get("Code");
			
			if(StringUtils.isEmpty(resCode)){
				TradeOrderInfo tradeOrderInfo = new TradeOrderInfo();
				tradeOrderInfo.setOrderNo(orderNo);
				tradeOrderInfo.setRefundTime(DateUtils.getDate());// 退款时间
				tradeOrderInfo.setStatus(TradeOrderInfoStatus.ORDER_COMPLETE_REFUND.getValue());// 4已退款
				//退款理由
				if(StringUtils.isNotEmpty(tradeOrderInfoTemp.getRefundReason())){
					tradeOrderInfo.setRefundReason(tradeOrderInfoTemp.getRefundReason());
				}
				tradeOrderInfoServiceImpl.updateByPrimaryKeySelective(tradeOrderInfo);
				strResponse = "success";
			}else{
				String errMsg = (String)map.get("ErrMsg");
				strResponse =  errMsg;
			}
		} catch (Exception e) {
			LOGGER.error("一网通退款接口出现异常！"+e.getMessage());
			strResponse = "faild";
		}
		
		return strResponse;
		
	}
	
}
